package com.yxhl.zoume.core.func.map.ui.fragment;


import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.yxhl.zoume.R;
import com.yxhl.zoume.UIConstants;
import com.yxhl.zoume.ZouMeApplication;
import com.yxhl.zoume.common.ui.fragment.BaseFragment;
import com.yxhl.zoume.core.func.map.view.BaseMapView;
import com.yxhl.zoume.domain.interactor.ZMEventSubscriber;
import com.yxhl.zoume.utils.DiskCacheUtils;
import com.yxhl.zoume.utils.LOG;
import com.yxhl.zoume.utils.ZMDialog;

import java.util.List;

import butterknife.BindView;

/**
 * Created by sugarya on 16/4/20 Email:sugarya@foxmail.com
 * 地图基类,含有地图UI配置和定位功能
 */
public abstract class BaseMapFragment extends BaseFragment
        implements BaseMapView, LocationSource, AMapLocationListener, AMap.OnMapLoadedListener {

    /**
     * 地图移动的动画时长
     */
    public static final int INITIAL_MOVE_ANIMATION_DURATION = 700;
    /**
     * 地图第一次移动到定位处的动画时长
     */
    public static final int LOCATION_MOVE_DELAY = 1000;
    private static final String TAG = "BaseMapFragment";
    private static final float DEFAULT_LOCATION_ZOOM_LEVEL = 10;
    /**
     * 地图移动的动画时长
     */
    private static final int CURRENT_MOVE_ANIMATION_DURATION = 500;
    //长沙(112.982279,28.19409)
    private static final LatLng AMP_DEFAULT_POSITION = new LatLng(28.19409, 112.982279);


    @BindView(R.id.map_include)
    public MapView mMapView;

    /**
     * 当前定位的城市
     */
    protected String mBaseLocationCity;


    protected AMapLocationClient mLocationClient;
    /**
     * 是否开始移动到定位处
     */
    protected boolean mBaseStartMoveToLocation = false;
    private LocationSource.OnLocationChangedListener mLocationChangeListener;
    /**
     * 地图加载完成标志
     */
    private boolean mHasMapLoad = false;
    /**
     * 定位激活标志
     */
    private boolean mHasLocationActive = false;
    private LatLng mCurrentLatLng;

    public BaseMapFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        mMapView.onCreate(savedInstanceState);
        AMap aMap = mMapView.getMap();

        setMapListener(aMap);
        configMap(aMap);

        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        checkLocationEnable();
    }

    /**
     * 检测手机GPS/定位是否开启
     */
    protected void checkLocationEnable() {
        LocationManager manager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
        boolean enabled = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if (!enabled) {
            ZMDialog dialog = new ZMDialog.Builder(mActivity)
                    .setCancelable(false)
                    .setMessage(getResString(R.string.dialog_base_map_open_location_setting))
                    .setPositiveMessage(getResString(R.string.dialog_open))
                    .setNegativeMessage(getResString(R.string.cancel))
                    .setPositiveClickEvent(new ZMEventSubscriber() {
                        @Override
                        public void onNext(Object o) {
                            super.onNext(o);
                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                            startActivity(intent);
                        }
                    })
                    .setNegativeClickEvent(new ZMEventSubscriber() {
                        @Override
                        public void onNext(Object o) {
                            super.onNext(o);

                        }
                    })
                    .show();
        }
    }

    /**
     * 配置地图
     */
    private void configMap(AMap aMap) {
        setUpMapUI(aMap);
        initializeLocation(aMap);
    }

    /**
     * 初始化地图UI
     *
     * @param aMap
     */
    private void setUpMapUI(AMap aMap) {
        CameraPosition.Builder cameraPositionBuilder = new CameraPosition.Builder();
        cameraPositionBuilder
                .bearing(0)
                .tilt(0)
                .zoom(DEFAULT_LOCATION_ZOOM_LEVEL)
                .target(AMP_DEFAULT_POSITION);
        //地图初始化默认显示的区域
        AMapOptions aMapOptions = new AMapOptions();
        aMapOptions.camera(CameraPosition.fromLatLngZoom(AMP_DEFAULT_POSITION, DEFAULT_LOCATION_ZOOM_LEVEL));

        // 隐藏缩放控件
        aMap.getUiSettings().setZoomControlsEnabled(false);
        // 屏蔽旋转手势
        aMap.getUiSettings().setRotateGesturesEnabled(false);
        //设置地图Logo位置
        aMap.getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_LEFT);

    }

    /**
     * 定位初始化
     *
     * @param aMap
     */
    private void initializeLocation(AMap aMap) {
        //定位激活 监听
        aMap.setLocationSource(this);
//        setUpLocationStyle(aMap)
        // 设置定位类型
        aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);

        //设置默认定位按钮是否显示
        aMap.getUiSettings().setMyLocationButtonEnabled(false);
        // 设置为true(定位激活)表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false(定位不激活)
        aMap.setMyLocationEnabled(true);

    }

    /**
     * 获取定位参数
     *
     * @return
     */
    private AMapLocationClientOption getLocationOption() {
        AMapLocationClientOption locationOption = new AMapLocationClientOption();
        //设置定位模式为高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
        locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
        //设置是否返回地址信息（默认返回地址信息）
        locationOption.setNeedAddress(true);
        //设置是否只定位一次,默认为false
        locationOption.setOnceLocation(false);
        //设置是否强制刷新WIFI，默认为强制刷新
        locationOption.setWifiActiveScan(true);
        //设置是否允许模拟位置,默认为false，不允许模拟位置
        locationOption.setMockEnable(false);
        //设置定位间隔,单位毫秒,默认为2000ms
        locationOption.setInterval(UIConstants.MAP_LOCATION_INTERVAL);

        return locationOption;
    }

    /**
     * 设置地图监听
     *
     * @param aMap
     */
    private void setMapListener(AMap aMap) {
        aMap.setOnMapLoadedListener(this);
    }

    @Override
    public void onMapLoaded() {
        mHasMapLoad = true;
        if (mHasLocationActive) {
            startLocation();
        }
    }

    /**
     * 定位激活 监听
     *
     * @param onLocationChangedListener
     */
    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mHasLocationActive = true;
        boolean isShowDefaultLocationIcon = setUpLocationStyle(mMapView.getMap());
        if (isShowDefaultLocationIcon) {
            mLocationChangeListener = onLocationChangedListener;
        }
        if (mHasMapLoad) {
            startLocation();
        }
    }

    /**
     * 开始定位
     */
    protected void startLocation() {
        if (mLocationClient == null) {
            mLocationClient = new AMapLocationClient(ZouMeApplication.application);
            mLocationClient.setLocationListener(this);
            mLocationClient.setLocationOption(getLocationOption());
            mLocationClient.startLocation();
        }
    }


    /**
     * 定位关闭 监听
     */
    @Override
    public void deactivate() {
        LOG.e(TAG, "deactivate");
        mHasLocationActive = false;
        mLocationChangeListener = null;
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
        mLocationClient = null;
    }


    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        //LOG.e(TAG, "AMapLocation=" + aMapLocation.toString());
        if (aMapLocation != null) {
            if (aMapLocation.getErrorCode() == 0) {
                locationChangedHandler(aMapLocation);
                onMapLocationChange();
            }
        }
    }

    /**
     * 地图定位回调
     */
    protected void onMapLocationChange() {
    }

    /**
     * 重新定位
     *
     * @param aMapLocation
     */
    public void locationChangedHandler(AMapLocation aMapLocation) {
        if (aMapLocation != null) {
            // 默认显示用户位置图标
            if (mLocationChangeListener != null) {
                mLocationChangeListener.onLocationChanged(aMapLocation);
            }

            if (TextUtils.isEmpty(mBaseLocationCity)) {
                //获取到定位城市
                mBaseLocationCity = aMapLocation.getCity();
                DiskCacheUtils.getInstance(getContext()).saveLocationCity(mBaseLocationCity);
            }

            //初始化定位图标
            double latitude = aMapLocation.getLatitude();
            double longitude = aMapLocation.getLongitude();
            getLocationMarker(mMapView.getMap(), new LatLng(latitude, longitude));

            if (mBaseStartMoveToLocation) {
                if (mCurrentLatLng == null) {
                    mCurrentLatLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            //动画移动
                            animateMoveTo(mCurrentLatLng);
                        }
                    }, LOCATION_MOVE_DELAY);
                }
            }
        }
    }

    /**
     * 地图移动到
     */
    protected void animateMoveTo(LatLng latLng, float zoomLevel) {
        if (latLng != null) {
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, zoomLevel);
            if (mMapView != null) {
                AMap aMap = mMapView.getMap();
                if (aMap != null) {
                    aMap.animateCamera(cameraUpdate, CURRENT_MOVE_ANIMATION_DURATION, null);
                }
            }
        }
    }

    /**
     * 地图按区域移动到
     *
     * @param latLngList 该区域包含的点集
     * @param padding    边距距离(像素单位)
     */
    protected void animateMoveTo(List<LatLng> latLngList, int padding) {
        if (latLngList != null && latLngList.size() > 0) {
            LatLngBounds.Builder builder = LatLngBounds.builder();
            for (LatLng latLng : latLngList) {
                builder.include(latLng);
            }
            LatLngBounds latLngBounds = builder.build();
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(latLngBounds, padding);
            if (mMapView != null) {
                AMap aMap = mMapView.getMap();
                if (aMap != null) {
                    aMap.animateCamera(cameraUpdate);
                }
            }
        }
    }

    /**
     * 地图移动到
     */
    private void animateMoveTo(final LatLng latLng) {
        if (latLng != null) {
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, getLocationMapZoomLevel());
            try {
                mMapView.getMap().animateCamera(cameraUpdate, INITIAL_MOVE_ANIMATION_DURATION, new AMap.CancelableCallback() {
                    @Override
                    public void onFinish() {
                        secondAnimateMove();
                    }

                    @Override
                    public void onCancel() {
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 初始化定位图标Marker,计算在地图的显示位置
     *
     * @param aMap
     * @param latLng
     */
    protected abstract Marker getLocationMarker(AMap aMap, LatLng latLng);

    /**
     * 设置默认定位样式
     *
     * @param aMap true 带地图默认定位,false反之
     */
    protected abstract boolean setUpLocationStyle(AMap aMap);

    /**
     * 默认显示的地图显示级数
     *
     * @return
     */
    protected abstract float getLocationMapZoomLevel();

    /**
     * 地图定位后第二次移动动画的回调
     */
    protected abstract void secondAnimateMove();


    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mMapView != null) {
            mMapView.onSaveInstanceState(outState);
        }
    }


    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroyView() {
        LOG.e(TAG, "onDestroyView");
        mHasMapLoad = false;

        if (mLocationClient != null) {
            mLocationClient.onDestroy();
            mLocationClient = null;
        }

        mMapView.onDestroy();
        super.onDestroyView();
    }


}
